package com.mew.slots.core.common.game;

import com.alibaba.fastjson.JSON;
import com.mew.common.enm.SlotsWinType;
import com.mew.common.entity.game.WinFree;
import com.mew.slots.core.common.game.vo.AwardLine;
import com.mew.slots.core.common.game.vo.BasePlayMsgs;
import com.mew.slots.core.common.messge.response.SlotsPlayResponseMessage;
import com.mew.slots.core.common.vo.StrategyGameVO;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;

/**
 * @author dylin
 * @create 2020/11/24 0024
 */
@Data
@Slf4j
public abstract class BaseGameService {
    public WinFree winFree;
    //最大免费次数 默认0 不限制
    private int maxFreeNumber=0;
    //免费累积开关  默认关闭
    private boolean freesAccumulateEnabler=false;

    /**
     * 注入最大免费次数
     * @return
     */
    public com.mew.slots.core.common.game.BaseGameService injMaxFreeNumber(int maxFreeNumber){
        this.maxFreeNumber=maxFreeNumber;
        return this;
    }
    /**
     * 开启免费场次累积
     * @return
     */
    public com.mew.slots.core.common.game.BaseGameService enableFreesAccumulate(){
        freesAccumulateEnabler=true;
        return this;
    }
    /**
     * 准备游戏 处理strategyGameVO和winFree
     */
    public SlotsPlayResponseMessage Ready(StrategyGameVO strategyGameVO) {

        //处理数据
        gameDispose(strategyGameVO);

        BasePlayMsgs res=startGame(strategyGameVO);

        return getResp(strategyGameVO,res);
    }
    /**
     *处理strategyGameVO和winFree
     */
    public void gameDispose(StrategyGameVO strategyGameVO){
        winFree = strategyGameVO.getWinFree();
        //特殊游戏 消除游戏也算特殊
        if(winFree.getBounsChange()>0){
            //免费压注使用winFree保存的压注信息
            strategyGameVO.setInBetNumber(winFree.getBet());
            strategyGameVO.setBetNumber(0);
            strategyGameVO.setWinType(SlotsWinType.Special.code());
        }
        //免费游戏
        else if (winFree.getFrees()>0){
            strategyGameVO.setInBetNumber(winFree.getBet());
            strategyGameVO.setBetNumber(0);
            strategyGameVO.setWinType(SlotsWinType.Free.code());
        }
        //普通游戏
        else {
            //压注保存 免费或者特殊使用
            winFree.setBet(strategyGameVO.getInBetNumber());
            strategyGameVO.setBetNumber(strategyGameVO.getInBetNumber());
            strategyGameVO.setWinType(SlotsWinType.None.code());
        }
    }
    /**
     *开始游戏
     */
    public abstract BasePlayMsgs startGame(StrategyGameVO player);
    /**
     * 自定义游戏数据处理 公共处理之前调用。确定具体message类型,自定义游戏数据处理
     *  自定义游戏处理基本在这个方法中处理，后置处理只做公共数据处理后仍然需要处理的逻辑
     */
    public abstract SlotsPlayResponseMessage myResp(WinFree winFree,BasePlayMsgs res);
    /**
     * 公共游戏数据处理
     */
    public SlotsPlayResponseMessage getResp(StrategyGameVO player,BasePlayMsgs res){
        SlotsPlayResponseMessage message =myResp(player.getWinFree(),res);
        processStrategyGameVO(player,res);
        processWinFree(player,res);
        processSlotsPlayResponseMessage(message,player.getWinFree(),res);
        myAfterResp(message,player,res);
        //奖池 最后改变
        if(res.getJp()>0){
            player.setWinType(SlotsWinType.Jackpot.code());
            message.setJpNo(res.getJp());
        }
        return message;
    }
    /**
    * 处理StrategyGameVO数据
    */
    private void processStrategyGameVO(StrategyGameVO player,BasePlayMsgs res){
        player.setPaymentNumber(res.getAllwin());
        player.setIconResult(JSON.toJSONString(res.getEndSlots()));
        player.setBetTimes((int)(player.getPaymentNumber()/player.getInBetNumber()/player.getLineNumber()));
        player.setBetNumber(player.getBetNumber()*res.getLine());
        if(res.getBouns()>0 || res.getFree()>0 || res.getJp()>0 ){
            player.setSpecial(true);
        }
    }
    /**
     * 处理WinFree数据
     */
    private void processWinFree(StrategyGameVO player,BasePlayMsgs res){
        WinFree winFree= player.getWinFree();
        //老免费 次数-1
        if(player.getWinType()==SlotsWinType.Free.code()){
            winFree.setFreeNumber(winFree.getFreeNumber()-1);
            //免费的最后一把 免费场次次数-1
            if(winFree.getFrees()>0&&winFree.getFreeNumber()==0){
                winFree.setFrees(winFree.getFrees()-1);
            }
        }
        //这把出免费 并且消除结束
        if (res.free>0&&!res.isChange()){
            //如果是免费累积模式 累积免费场次次数  不累积免费次数
            if(freesAccumulateEnabler){
                winFree.setFrees(winFree.getFrees()+1);
            }
            //普通模式 累积免费次数
            else{
                winFree.setFrees(1);
                int newFreeNumber=winFree.getFreeNumber()+res.getFreeNumber();
                if(maxFreeNumber>0){
                    newFreeNumber=newFreeNumber>maxFreeNumber?maxFreeNumber:newFreeNumber;
                }
                winFree.setFreeNumber(newFreeNumber);
            }
            winFree.setFreeCount(winFree.getFreeCount()+res.getFreeNumber());
        }else{
            res.setFree((byte)0);
        }
        //出免费 清空免费总场次
        if(winFree.getFrees()==0){
            winFree.setFreeCount(0);
        }
        //普通游戏 且赢了钱    就能比倍
        if(player.getWinType()== SlotsWinType.None.code()&&res.getAllwin()>0){
            winFree.setBounsBibei(1);

        }
        //是否有消除
        winFree.setBounsChange(res.isChange()?1:0);

        //游戏数据记录
        winFree.setLastIcon(player.getIconResult());
        winFree.setLastLineNumber(res.getLine());
        winFree.setLastBetNumber(player.getInBetNumber());
        winFree.setLastWinNumber(res.getAllwin());
    }
    /**
     * 处理SlotsPlayResponseMessage数据
     */
    private void processSlotsPlayResponseMessage(SlotsPlayResponseMessage message,WinFree winFree,BasePlayMsgs res){
        //=============基本===========================
        message.setBetNumber(res.getBet());
        //图案
        message.setIcons(res.getEndSlots());
        //闪图案
        message.setLight(res.getUv());
        //赢
        message.setWinCoin(res.getAllwin());
        //总倍数
        message.setTotalMultiple((int)(res.getAllwin()/res.getBet()/res.getLine()));
        //每条线中啥
        ArrayList<BasePlayMsgs.LineResult> lines = res.getLines();
        message.setAwardLines(new AwardLine[lines.size()]);
        for (int i = 0; i < lines.size(); i++) {
            BasePlayMsgs.LineResult x = lines.get(i);
            AwardLine awardLine = new AwardLine();
            awardLine.setId(x.getLineNum()+1);
            awardLine.setType(x.getType());
            awardLine.setNum(x.getNum());
            awardLine.setMult(x.getMult());
            awardLine.setWin(res.getBet()*x.getMult());
            message.getAwardLines()[i] = awardLine;
        }
        //============免费====================================
        message.setFree(res.getFree());
        message.setFreeNumber(winFree.getFreeNumber());
    }
    /**
     * 自定义后置游戏数据处理 公共处理之后需要自定义调整的数据调整
     */
    public abstract void myAfterResp(SlotsPlayResponseMessage message,StrategyGameVO player,BasePlayMsgs res);

}
